﻿using Reactor.Environment.Workflows;
using Reactor.Exceptions;
using Samurai.Wakizashi.Workflow;

namespace Reactor.Environment
{
    /// <summary>
    /// Class containing all database connection strings and information necessary for 
    /// connecting to a ReactorServices database, a messaging broker, and package repositories. 
    /// </summary>
    public class PlatformConnectionData
    {
        /// <summary>
        /// Gets or sets the workflow to execute initilization logic. 
        /// <remarks>This workflow is responsible for  obtaining database connection information, 
        /// messaging broker information, and package repository information (if necessary). The workflow 
        /// is executed when the Initialize method is called on this 
        /// <seealso cref="PlatformConnectionData"/> instance.</remarks>
        /// </summary>
        /// <value>The initilization workflow.</value>
        public IWorkflow<InitializationContext> InitilizationWorkflow { get; set; }

        /// <summary>
        /// Gets or sets the database connection string.
        /// </summary>
        /// <value>The database connection string.</value>
        public string DatabaseConnectionString { get; set; }

        /// <summary>
        /// Gets or sets the broker details.
        /// </summary>
        /// <value>The broker details.</value>
        public BrokerConnectionDetails BrokerDetails { get; set; }

        /// <summary>
        /// Gets or sets the package repository location.
        /// </summary>
        /// <value>The package repository location.</value>
        public string PackageRepositoryLocation { get; set; }

        /// <summary>
        /// Initializes this instance by executing the workflow instance provided in 
        /// the <see cref="InitilizationWorkflow"/> property of this instance.
        /// <remarks>If the <see cref="InitilizationWorkflow"/> property is null when 
        /// this method is called, a <seealso cref="DefaultEnvironmentBootstrapper"/> 
        /// instance is created and used instead.</remarks>
        /// </summary>
        public void Initialize()
        {
            if (InitilizationWorkflow == null)
                InitilizationWorkflow = new DefaultEnvironmentBootstrapper();

            InitilizationWorkflow.WorkflowFailed += InitilizationWorkflow_WorkflowFailed;
            InitilizationWorkflow.Start();

            DatabaseConnectionString = InitilizationWorkflow.Context.DatabaseConnectionString;
            BrokerDetails = InitilizationWorkflow.Context.BrokerDetails;
            PackageRepositoryLocation = InitilizationWorkflow.Context.PackageRepositoryLocation;
        }

        private static void InitilizationWorkflow_WorkflowFailed(object sender, WorkflowCompletedEventArgs<InitializationContext> e)
        {
            throw new FatalException("Unable to initialize PlatformConnectionData", e.Exception);
        }
    }
}
